const Captcha = require("@/utils/captcha");
const NodeCache = require("@/utils/node_cache");
const Crypto = require("crypto");
const Bcrypt = require("bcryptjs");
const Jwt = require("jsonwebtoken");
const { getMemberByAccount, bindWxUser } = require("@/models/v1/member-model");
const axios = require("axios");

exports.uploadImage = async (req, res, next) => {
  try {
    const file = req.file;
    // const path = require("path");
    // const fse = require("fs-extra");
    // const source = path.resolve(file.path);
    // const newFilePath = "public/thing/imgs/" + file.filename;
    // const target = path.resolve(newFilePath);
    // await fse.move(source, target); // 移动
    // await fse.remove(source); // 删除源文件
    return res.backSuccess({ ...file, path: file.destination + file.filename });
  } catch (error) {
    next(error);
  }
};

/**
 * 刷新token
 */
exports.refreshToken = async (req, res, next) => {
  try {
    const { refresh_token } = req.body;
    if (!refresh_token || refresh_token == "") {
      throw new Error("access_token不能为空");
    }
    Jwt.verify(refresh_token, process.env.JWT_REFRESH_KEY, (err, result) => {
      if (err) throw new Error("无效的refresh_token");

      const access_token = Jwt.sign(
        { id: result.id, account: result.account },
        process.env.JWT_KEY,
        { expiresIn: "1d" }
      );
      const refresh_token = Jwt.sign(
        { id: result.id, account: result.account },
        process.env.JWT_REFRESH_KEY,
        {
          expiresIn: "7d",
        }
      );

      return res.backSuccess({
        id: result.id,
        account: result.account,
        access_token,
        refresh_token,
      });
    });
  } catch (error) {
    next(error);
  }
};

/**
 * 获取登录用户信息
 */
exports.member = async (req, res, next) => {
  try {
    const { account, id } = req.auth;
    var member = await getMemberByAccount({ id, account });
    delete member.password;
    delete member.session_key;
    res.backSuccess(member);
  } catch (error) {
    next(error);
  }
};

/**
 * 绑定微信小程序
 */
exports.bindWx = async (req, res, next) => {
  try {
    // 请求微信授权
    const wx_code = req.query.code;
    const wx_url = `https://api.weixin.qq.com/sns/jscode2session?appid=${process.env.WEIXIN_APPID}&secret=${process.env.WEIXIN_APPSECRET}&js_code=${wx_code}&grant_type=authorization_code`;
    const wx_result = await axios.get(wx_url);
    if (!wx_result.data.session_key || !wx_result.data.openid) {
      if (wx_result.data.errcode == 40029) throw new Error("无效CODE");
      throw new Error("系统繁忙，请稍候再试");
    }
    // 判断当前微信是否已经绑定其他账号
    const isBindMember = await getMemberByAccount({
      openid: wx_result.data.openid,
    });
    if (isBindMember) {
      throw new Error("当前微信已绑定其他账号~");
    }

    const { account, id } = req.auth;
    var isMember = await getMemberByAccount({ id, account });
    if (!isMember) {
      throw new Error("账号不存在");
    }
    // 绑定
    const bindResult = await bindWxUser({
      id,
      openid: wx_result.data.openid,
      session_key: wx_result.data.session_key,
    });
    res.backSuccess(bindResult);
  } catch (error) {
    next(error);
  }
};

exports.loginWx = async (req, res, next) => {
  try {
    // 请求微信授权
    const wx_code = req.query.code;
    const wx_url = `https://api.weixin.qq.com/sns/jscode2session?appid=${process.env.WEIXIN_APPID}&secret=${process.env.WEIXIN_APPSECRET}&js_code=${wx_code}&grant_type=authorization_code`;
    const wx_result = await axios.get(wx_url);
    if (!wx_result.data.session_key || !wx_result.data.openid) {
      if (wx_result.data.errcode == 40029) throw new Error("无效CODE");
      throw new Error("系统繁忙，请稍候再试");
    }
    var result = await getMemberByAccount({ openid: wx_result.data.openid });
    if (!result) {
      throw new Error("绑定微信后才可以一键授权登录~");
    }
    const access_token = Jwt.sign(
      { id: result.id, account: result.account },
      process.env.JWT_KEY,
      { expiresIn: "1d" }
    );
    const refresh_token = Jwt.sign(
      { id: result.id, account: result.account },
      process.env.JWT_REFRESH_KEY,
      {
        expiresIn: "7d",
      }
    );

    return res.backSuccess({
      id: result.id,
      account: result.account,
      access_token,
      refresh_token,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * 登录
 */
exports.login = async (req, res, next) => {
  try {
    var queryParams = req.query;
    var validateCode = NodeCache.get(queryParams.key);

    if (
      !validateCode ||
      validateCode.toLowerCase() != queryParams.code.toLowerCase()
    ) {
      throw new Error("验证码错误");
    }

    var result = await getMemberByAccount({ account: queryParams.account });

    if (!result || !Bcrypt.compareSync(queryParams.password, result.password)) {
      throw new Error("账号或密码错误");
    }

    const access_token = Jwt.sign(
      { id: result.id, account: result.account },
      process.env.JWT_KEY,
      { expiresIn: "1d" }
    );
    const refresh_token = Jwt.sign(
      { id: result.id, account: result.account },
      process.env.JWT_REFRESH_KEY,
      {
        expiresIn: "7d",
      }
    );

    return res.backSuccess({
      id: result.id,
      account: result.account,
      access_token,
      refresh_token,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * 验证码
 */
exports.captcha = async (req, res, next) => {
  try {
    const isBase64 = req.query.isBase64 || 0;
    // 生成验证码
    const { data, text } = Captcha({
      is_sum: true,
      config: { width: 120, height: 40, fontSize: 50 },
    });
    var image = data;
    // 生成唯一键
    const key = Crypto.randomUUID();
    // 存入redis
    NodeCache.set(key, text, 600);

    console.log("====>" + key);
    console.log("====>" + text);

    if (isBase64 == 1) {
      // 将SVG代码转换为UTF-8编码的字节数组
      const utf8Bytes = new TextEncoder().encode(data);
      // 将字节数组编码为Base64
      image =
        "data:image/svg+xml;base64," +
        btoa(String.fromCharCode.apply(null, utf8Bytes));
    }

    res.backSuccess({ image, key });
  } catch (error) {
    next(error);
  }
};
